package sample.test.cc.cool.gui.controllers;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import java.util.Set;

import sample.test.cc.cool.TransactionManager;
import sample.test.cc.cool.gui.client.GuiClient;
import BESA.SystemLevel.AdmBESA;
import BESA.SystemLevel.transactions.agent.Intention;

public class ClientController implements Observer {
	
	private GuiClient gui = null;
	private TransactionManager manager = null;
	private Set<String> agentsAlias = null;
	private static  ClientController instance= null;
	private List<Long> activeTransaction = null; 
	
	private ClientController(){
		AdmController.getInstance().addObserver(this);
		activeTransaction = new ArrayList<Long>();
		agentsAlias = new HashSet<String>();
	}
	
	
	public synchronized static ClientController getInstance(){
		if(instance == null)
			instance = new ClientController();
		return instance;
	}
	
	public synchronized void startGui(){
		gui = new GuiClient();
		gui.setVisible(true);
		manager= new TransactionManager();
		if(AdmController.existContainner)
			gui.updateAgentList(agentsAlias);
	}

	public synchronized void showCreateDialog(){
		AdmController.getInstance().showCreateDialog(gui);
	}


	@Override
	public synchronized void update(Observable o, Object arg) {
		if(o instanceof AdmController){
			if(manager == null)
				manager = new TransactionManager();
			else
				manager.setAdmin(AdmBESA.getInstance());
		}
	}
	
	public synchronized Set<String> getAllAgentsAlias() {
		return agentsAlias;
	}

	

	public synchronized void openTransaction() {
		long transaction = manager.openTransaction();
		activeTransaction.add(transaction);
		this.updateTransactionComboBoxes();
	}
	
	public void updateTransactionComboBoxes(){
		gui.updateTransactionComboBoxes(activeTransaction);
	}


	public synchronized boolean closeTransaction(long parseLong) {
		boolean ret = manager.closeTransaction(parseLong);
		this.activeTransaction.remove(parseLong);
		this.updateTransactionComboBoxes();
		return ret;
	}


	public synchronized void sendEvent(String alias, Long transaction, Intention in, int ... values ) {
		
		System.err.println("___CONTROLLER");
		if(in.toString().equals("READ")){
			new sendEventThread(manager, alias, transaction, in);
		}else{
			new sendEventThread(manager, alias, transaction, in, values[0]);
		}
		
		
	}
	
	public synchronized void addNewAgent(String alias){
		if(!alias.contains("_COPY_") &&agentsAlias.add(alias)){
			if(gui != null){
				gui.updateAgentList(agentsAlias);
			}
		}
	}
	
}

class sendEventThread extends Thread{
	
	String alias;
	Long transaction; 
	Intention in;
	int value= Integer.MIN_VALUE;
	TransactionManager manager;
	
	
	public sendEventThread(TransactionManager manager,String alias, Long transaction, Intention in) {
		super();
		this.manager = manager;
		this.alias = alias;
		this.transaction = transaction;
		this.in = in;
		this.start();
	}



	public sendEventThread(TransactionManager manager,String alias, Long transaction, Intention in,
			int value) {
		super();
		this.manager = manager;
		this.alias = alias;
		this.transaction = transaction;
		this.in = in;
		this.value = value;
		this.start();
	}



	@Override
	public void run() {
		System.err.println("__INNER THREEAD");
		if(value== Integer.MIN_VALUE){
			manager.execTransaction(transaction, alias, in);
		}
		else{
			manager.execTransaction(transaction, alias, in, value);
		}
	}
	
}
